"""
@File    :   password_encryption.py
@Time    :   2024/02/23 10:24:20
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   密码加密相关工具类
"""

import bcrypt
from asyncer import asyncify

from src.config import get_app_settings

# 获取应用配置
settings = get_app_settings()


class PswHashUtil:
    """密码加密(hash)工具类"""

    @staticmethod
    def hash_psw(psw: str) -> str:
        """对密码进行hash

        Args:
            psw (str): 密码明文

        Returns:
            str: 密码hash
        """
        # 每次加密都进行一次salt生成, 让每次加密的hash都不同
        salt = bcrypt.gensalt(rounds=settings.bcrypt_rounds)
        hashed = bcrypt.hashpw(psw.encode(), salt)
        return hashed.decode()

    @staticmethod
    def verify_psw(plain_psw: str, hashed_psw: str) -> bool:
        """验证密码明文与hash

        Args:
            plain_psw (str): 密码明文
            hashed_psw (str): 密码hash

        Returns:
            bool: 是否验证成功
        """
        try:
            result = bcrypt.checkpw(plain_psw.encode(), hashed_psw.encode())
        except Exception:
            result = False
        return result

    @staticmethod
    async def async_hash_psw(psw: str) -> str:
        """对密码进行hash(异步)

        Args:
            psw (str): 密码明文

        Returns:
            str: 密码hash
        """
        return await asyncify(PswHashUtil.hash_psw)(psw=psw)

    @staticmethod
    async def async_verify_psw(plain_psw: str, hashed_psw: str) -> bool:
        """验证密码明文与hash

        Args:
            plain_psw (str): 密码明文
            hashed_psw (str): 密码hash

        Returns:
            bool: 是否验证成功
        """
        return await asyncify(PswHashUtil.verify_psw)(
            plain_psw=plain_psw, hashed_psw=hashed_psw
        )
